package com.zzyy.study.controller;

import com.zzyy.study.lock.DistributeLock;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @auther zzyy
 * @create 2024-08-27 16:11
 */
@RestController
@Slf4j
public class TestController {

    @Resource
    private DistributeLock distributeLock;

    /**
     * 测试用例1：无阻塞式获取锁,等价于JUC里面的lock.tryLock()
     * http://localhost:24096/tryLockRun
     * @return
     */
    @GetMapping("/tryLockRun")
    public String tryLockRun() {
        long startTime = System.currentTimeMillis();
        log.info("tryLockRun start");
        // 获取锁的过程不会阻塞，成功获取锁后将执行业务，业务执行完成后自动释放锁，并返回true；若无法获取锁，则会立即返回false
        boolean lockResult = this.distributeLock.tryLockRun("lock1", () -> {
            log.info("获取锁成功，执行业务");
            //暂停3秒钟线程
            try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
            log.info("---执行业务耗时3秒钟");
        });

        log.info("耗时：{},{}", (System.currentTimeMillis() - startTime), lockResult ? "获取锁成功" : "获取锁失败");
        return lockResult ? "获取锁成功" : "获取锁失败";
    }

    /**
     * 测试用例2：获取锁有超时时间，等价于JUC里面
     *     boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
     *
     *     http://localhost:24096/tryLockRunWaitTime
     * @return
     */
    @GetMapping("/tryLockRunWaitTime")
    public String tryLockRunWaitTime() {
        long startTime = System.currentTimeMillis();
        log.info("tryLockRunWaitTime start");

        //这个尝试获取锁，最多等待1秒，成功获取锁后将执行业务，业务执行完成后自动释放锁，并返回true；若1秒无法获取锁，则返回false
        boolean lockResult = this.distributeLock.tryLockRun("lock1", () -> {
            log.info("获取锁成功，我最多等待1秒，执行业务");
            //暂停4秒钟线程
            try { TimeUnit.SECONDS.sleep(4); } catch (InterruptedException e) { e.printStackTrace(); }
            log.info("---执行业务耗时4秒钟");
        }, 1, TimeUnit.SECONDS);

        log.info("耗时：{},{}", (System.currentTimeMillis() - startTime), lockResult ? "获取锁成功" : "获取锁失败");
        return lockResult ? "获取锁成功" : "获取锁失败";
    }

    /**
     * 测试用例3：获取锁会阻塞，直到成功获取锁,等价于JUC里面的 void lock(); lockRun =  lock  or  synchronized
     * http://localhost:24096/lockRun
     * @return
     */
    @GetMapping("/lockRun")
    public String lockRun() {
        long startTime = System.currentTimeMillis();
        log.info("lockRun start");
        //获取锁的过程会阻塞，直到成功获取锁，成功获取锁后将执行业务，业务执行完成后自动释放锁
        this.distributeLock.lockRun("lock1", () -> {
            log.info("获取锁成功，执行业务");
            //暂停5秒钟线程
            try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }
            log.info("---执行业务耗时5秒钟");
        });
        log.info("获取锁成功,耗时：{}", (System.currentTimeMillis() - startTime));
        return "获取锁成功";
    }

}
